package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.pojo.goods.Sku;
import com.qingcheng.pojo.order.OrderItem;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.order.CartService;
import com.qingcheng.service.order.PreferentialService;
import com.qingcheng.util.CacheKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService{

    @Autowired
    private RedisTemplate redisTemplate;

    @Reference
    private SkuService skuService;
    /**
     * 查看购物车清单
     * @param username
     * @return
     */
    @Override
    public List<Map<String, Object>> findCartList(String username) {

        //从redis中获取该用户的购物车
        List<Map<String, Object>> mapList = (List<Map<String, Object>>) redisTemplate.boundHashOps(CacheKey.CART_LIST).get(username);
        //如果获取不到构建一个空的购物车
        if (mapList==null){
            mapList = new ArrayList<>();
        }
        return mapList;
    }

    /**
     * 添加商品到购物车(遍历redis中的购物车,如果购物车中有要添加的商品对数量进行修改,如果没有就新增一个订单详情)
     * @param username
     * @param skuId
     * @param num
     */
    @Override
    public void addItem(String username, String skuId, Integer num) {
        //先查一下购物车,有没有该商品,如果没有就添加,如果有数量上+num
        List<Map<String, Object>> cartList = findCartList(username);
        Boolean flag = false;//判断商品是否存在于购物车中
        for (Map<String, Object> map : cartList) {
            OrderItem item = (OrderItem) map.get("item");
            if (item.getNum()<=0){
                cartList.remove(map);
                break;
            }

            if(item.getSkuId().equals(skuId)){ //如果购物车中有相同的商品
                int money = item.getMoney()/item.getNum(); //单价
                int weight = item.getWeight() / item.getNum(); //单个商品重量
                item.setNum(item.getNum()+num); //数量变动
                item.setMoney(money*item.getNum()); //重新设置金额
                item.setWeight(weight*item.getNum());
                if (item.getNum()<=0){
                    cartList.remove(map);
                }
                flag=true;
                break;
            }


        }

        if (flag==false){  //如果商品不存在就添加这个商品

            Sku sku = skuService.findById(skuId);
            if (sku==null){
                throw new RuntimeException("商品不存在");
            }
            if (num<0){
                throw new RuntimeException("数量不合法");
            }
            if (!sku.getStatus().equals("1")){
                throw new RuntimeException("商品状态不合法");
            }
            Map<String, Object> map_new = new HashMap<>();
            OrderItem item = new OrderItem();
            item.setSkuId(skuId);
            item.setName(sku.getName());
            item.setSpuId(sku.getSpuId());
            item.setImage(sku.getImage());
            item.setPrice(sku.getPrice());
            item.setNum(num);
            item.setMoney(sku.getPrice() * num); //计算总金额
            if (sku.getWeight() == null) {  //一些商品没有重量时，设置重量为0
                sku.setWeight(0);
            }
            item.setWeight(sku.getWeight() * num); //计算总重量
            item.setCategoryId3(sku.getCategoryId());
            map_new.put("item", item);
            map_new.put("checked", true);  //默认为选中状态
            cartList.add(map_new);

        }

        //重新写回redis
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,cartList);

    }

    /**
     * 更新购物车选择框的状态
     * @param username
     * @param skuId
     * @param checked
     * @return
     */
    @Override
    public boolean updateChecked(String username, String skuId, boolean checked) {
        List<Map<String, Object>> cartList = findCartList(username);
        Boolean flag = false;
        for (Map<String, Object> map : cartList) {
            OrderItem orderItem = (OrderItem) map.get("item");
            if (orderItem.getSkuId().equals(skuId)) {
                map.put("checked",checked);
                flag=true;
                break;
            }
        }

        if (flag){ //如果商品的状态更新那么就更新缓存
            redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,cartList);
        }

        return flag;
    }

    /**
     * 删除选中
     * @param username
     */
    @Override
    public void deleteCheckedCart(String username) {
        //筛选出所有的未被选中状态
        List<Map<String, Object>> checked = findCartList(username).stream()
                .filter(cart -> (Boolean) cart.get("checked") == false)
                .collect(Collectors.toList());
        //把未被选中的重新存到redis中(相当于删除选中的数据)
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,checked);

    }

    @Autowired
    private PreferentialService preferentialService;
    /**
     * 计算当前购物车中的优惠金额
     * @param username
     * @return
     */
    @Override
    public int preferential(String username) {
        //对购物车中的商品进行分类,每个类目的优惠不一样
        int money = 0;
        List<OrderItem> orderItems = findCartList(username).stream()
                .filter(cart -> (Boolean) cart.get("checked") == true)
                .map(cart -> (OrderItem) cart.get("item")).collect(Collectors.toList());
        //按分类聚合每个分类的总金额
        Map<Integer, IntSummaryStatistics> cartMap = orderItems.stream()
                .collect(Collectors.groupingBy(OrderItem::getCategoryId3, Collectors.summarizingInt(OrderItem::getMoney)));
        //定义一个总的优惠金额
        int totalPreMoney = 0;
        //循环遍历 ，统计每个分类下的优惠金额
        for (Integer categoryId : cartMap.keySet()) {
            // 获取品类的消费金额
            int money1 = (int) (cartMap.get(categoryId).getSum());
            // 获取品类的优惠金额
            Integer perMoney = preferentialService.preferential(categoryId, money1);
            System.out.println("分类ID:"+categoryId+"消费金额:"+money+"优惠金额:"+perMoney);
            totalPreMoney += perMoney;
        }
        return totalPreMoney;

    }

    /**
     * 获取最新的购物车信息(再查一次数据库,确保价格等敏感信息时最先的)
     * @param username
     * @return
     */
    @Override
    public List<Map<String, Object>> findNewOrderItemList(String username) {
        //获取选中的购物车信息
        List<Map<String, Object>> cartList = findCartList(username);
        //重新读取购物车中每个商品的最新价格
        for (Map<String, Object> cart : cartList) {
            OrderItem orderItem = (OrderItem)cart.get("item");
            Sku sku = skuService.findById(orderItem.getSkuId());

            orderItem.setPrice(sku.getPrice());
            orderItem.setMoney(sku.getPrice()*orderItem.getNum());

        }

        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username,cartList);

        return cartList;
    }

}
